<?php

namespace app\api\service;

use app\api\model\User as UserModel;
use app\lib\enum\UserScope;
use app\lib\exception\TokenMissException;
use think\Exception;

class UserToken extends Token
{
    protected $code;
    protected $appID;
    protected $appSecret;
    protected $loginUrl;
    
    public function __construct($code)
    {
        parent::__construct([]);

        $this->code = $code;
        $this->appID = config('wx.app_id');
        $this->appSecret = config('wx.app_secret');
        $this->loginUrl = sprintf(config('wx.login_url'), $this->appID, $this->appSecret, $this->code);
    }
    
    //获取 token
    public function getToken()
    {
        $result   = curl_get($this->loginUrl, $httpCode);
        $wxresult = json_decode($result, true);

        if (empty($wxresult)) {
            throw new Exception('请求登录信息失败');
        } else {
            $loginFail = array_key_exists('errcode', $wxresult);
            if ($loginFail) {
                throw new Exception('微信登录接口返回信息失败');
            } else {
                $token = $this->grantToken($wxresult);
                return $token;
            }
        }
    }

    //保存 token
    public function grantToken($wxResult)
    {
        $openID = $wxResult['openid'];

        $userInfo = UserModel::getUserInfoByOpenID($openID);
        if ( $userInfo) {
            $uid = $userInfo->id;
        } else {
            $uid = $this->createUser($wxResult);
        }

        $cachedValue = $this->prepareCachedValue($wxResult, $uid);
        $key = $this->saveCachedValue($cachedValue);

        return $key;
    }

    /**
     * 创建用户信息 并返回用户 ID
     * @param $wxResult
     * @return mixed
     */
    protected function createUser($wxResult)
    {
        $user = UserModel::create([
            'openid' => $wxResult['openid']
        ]);

        return $user->id;
    }


    /**
     * 保存用户信息; scope 表示权限范围, 越大表示权限越大
     * @param $wxResult
     * @param $uid
     */
    protected function prepareCachedValue($wxResult, $uid)
    {
        $cachedValue = $wxResult;
        $cachedValue['uid'] = $uid;
        //用户 APP 权限
        $cachedValue['scope'] = UserScope::USER;

        return $cachedValue;
    }

    /*
     * 将数据写入缓存
     * @param $cachedValue
     * @return string
     * @throws TokenMissException
     */
    private function saveCachedValue($cachedValue)
    {
        $key = self::generateToken();
        $value = json_encode($cachedValue);
        $expire_in = config('setting.expire_in');
        
        $request = cache($key, $value, $expire_in);
        if ( !$request) {
            throw new TokenMissException();
        }

        return $key;
    }


}